package app.itgungnir.compose.wan.widgets

import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Alarm
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import app.itgungnir.compose.wan.theme.WanComposePreviewTheme
import com.google.accompanist.insets.statusBarsHeight
import kotlinx.coroutines.Job

@Composable
fun WanStatusBar(modifier: Modifier = Modifier, statusBarColor: Color = MaterialTheme.colors.primaryVariant) {
    Box(
        modifier = modifier
            .fillMaxWidth()
            .statusBarsHeight()
            .background(color = statusBarColor)
    )
}

@Composable
fun WanTopBar(
    withStatusBar: Boolean = true,
    statusBarColor: Color = MaterialTheme.colors.primaryVariant,
    title: String?,
    canGoBack: Boolean = true,
    backgroundColor: Color = MaterialTheme.colors.primary,
    tintColor: Color = MaterialTheme.colors.onPrimary,
    navController: NavController = rememberNavController()
) {
    Surface(elevation = 4.dp) {
        Column(modifier = Modifier.fillMaxWidth()) {
            if (withStatusBar) {
                WanStatusBar(statusBarColor = statusBarColor)
            }
            if (title?.isNotEmpty() == true) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(color = backgroundColor)
                        .padding(vertical = 2.dp),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = if (canGoBack) Arrangement.Start else Arrangement.Center
                ) {
                    if (canGoBack) {
                        WanIconButton(icon = Icons.Filled.ArrowBack) { navController.navigateUp() }
                    }
                    WanHeader(modifier = Modifier.padding(vertical = 12.dp), content = title, color = tintColor)
                }
            }
        }
    }
}

@Preview(name = "WanTopBar light mode", showBackground = true)
@Preview(name = "WanTopBar dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Composable
private fun WanTopBarPreview() {
    WanComposePreviewTheme {
        WanTopBar(title = "Test WanTopBar Text")
    }
}

@Composable
fun WanScaffold(
    modifier: Modifier = Modifier,
    title: String? = null,
    canGoBack: Boolean = true,
    showStatusBar: Boolean = true,
    statusBarColor: Color = MaterialTheme.colors.primaryVariant,
    navController: NavController = rememberNavController(),
    loadingState: State<Boolean> = mutableStateOf(false),
    loadingMessage: String = "Loading...",
    loadingJob: Job? = null,
    errorState: State<Throwable?>? = mutableStateOf(null),
    bottomBar: @Composable () -> Unit = {},
    floatingActionButton: @Composable () -> Unit = {},
    component: @Composable (PaddingValues) -> Unit
) {
    val scaffoldState = rememberScaffoldState()
    Scaffold(
        modifier = modifier,
        topBar = {
            WanTopBar(
                withStatusBar = showStatusBar,
                statusBarColor = statusBarColor,
                title = title,
                navController = navController,
                canGoBack = canGoBack
            )
        },
        scaffoldState = scaffoldState,
        bottomBar = bottomBar,
        floatingActionButton = floatingActionButton
    ) {
        component(it)
    }
    WanLoadingDialog(state = loadingState, message = loadingMessage) {
        loadingJob?.cancel()
    }
    LaunchedEffect(key1 = errorState?.value) {
        errorState?.value?.message?.takeIf { it.isNotEmpty() }?.let { message ->
            scaffoldState.snackbarHostState.showSnackbar(message = message)
        }
    }
}

@Preview(name = "WanScaffold light mode", showBackground = false)
@Preview(name = "WanScaffold dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = false)
@Composable
private fun WanScaffoldPreview() {
    WanComposePreviewTheme {
        WanScaffold(
            title = "标题标题标题标题标题",
            bottomBar = {
                Row(modifier = Modifier.fillMaxWidth()) {
                    Icon(modifier = Modifier.weight(1F), imageVector = Icons.Filled.Alarm, contentDescription = "")
                    Icon(modifier = Modifier.weight(1F), imageVector = Icons.Filled.Alarm, contentDescription = "")
                    Icon(modifier = Modifier.weight(1F), imageVector = Icons.Filled.Alarm, contentDescription = "")
                }
            },
            floatingActionButton = {
                FloatingActionButton(onClick = { }) {
                    Icon(imageVector = Icons.Filled.Add, contentDescription = "")
                }
            }
        ) {
            WanTitle(content = "Simple Scaffold Content")
        }
    }
}

@Composable
fun WanCustomScaffold(
    modifier: Modifier = Modifier,
    showStatusBar: Boolean = true,
    statusBarColor: Color = MaterialTheme.colors.primaryVariant,
    loadingState: State<Boolean> = mutableStateOf(false),
    loadingMessage: String = "Loading...",
    loadingJob: Job? = null,
    errorState: State<Throwable?>? = mutableStateOf(null),
    topBar: @Composable () -> Unit = {},
    bottomBar: @Composable () -> Unit = {},
    floatingActionButton: @Composable () -> Unit = {},
    component: @Composable (PaddingValues) -> Unit
) {
    val scaffoldState = rememberScaffoldState()
    Scaffold(
        modifier = modifier,
        topBar = {
            Surface(elevation = 4.dp) {
                Column(modifier = Modifier.fillMaxWidth()) {
                    if (showStatusBar) {
                        WanStatusBar(statusBarColor = statusBarColor)
                    }
                    topBar()
                }
            }
        },
        scaffoldState = scaffoldState,
        bottomBar = bottomBar,
        floatingActionButton = floatingActionButton
    ) {
        component(it)
    }
    WanLoadingDialog(state = loadingState, message = loadingMessage) {
        loadingJob?.cancel()
    }
    LaunchedEffect(key1 = errorState?.value) {
        errorState?.value?.message?.takeIf { it.isNotEmpty() }?.let { message ->
            scaffoldState.snackbarHostState.showSnackbar(message = message)
        }
    }
}
